import { menu } from '../../../app/decorator';
import BasePlay from './base/BasePlay';

const { ccclass, property, requireComponent } = cc._decorator;

interface IComplete {
    (success?: boolean): void
}

@ccclass
@menu(__filename)
@requireComponent(cc.Animation)
export default class PlayAnimation extends BasePlay {
    @property
    private _animation: string = '';
    @property
    get animation() { return this._animation; }
    set animation(value) {
        this._animation = value;
        if (CC_EDITOR) {
            this._play(-1);
        } else {
            this._play();
        }
    }

    static Event = {
        animationPlay: 'animationPlay',
        animationStop: 'animationStop',
        animationPause: 'animationPause',
        animationResume: 'animationResume',
        animationComplete: 'animationComplete'
    };

    // animation组件
    private __currAni: cc.Animation = null;
    private get _currAni(): cc.Animation {
        if (!this.__currAni) this.__currAni = this.node.getComponent(cc.Animation);
        return this.__currAni;
    }
    private _currDt: number = 0;
    // 完成回调
    private _completeCallback: IComplete = null;
    // 是否完成
    private _isCompelte = false;

    onLoad() {
        this._currAni.playOnLoad = false;

        super.onLoad();
    }

    protected _play(loopCount?: number): boolean {
        this.stop();

        if (!this.animation) return false;
        if (!this._currAni.getAnimationState(this.animation)) return false;

        this._isCompelte = false;

        // const state = this._currAni.getAnimationState(this.animation);
        // duration 动画的持续时间
        // frameRate 动画的帧速率
        // speed 动画的播放速度
        // state.duration / state['frameRate']
        this._currDt = 0;
        super.basePlay(0, loopCount);

        return true;
    }

    protected _render(dt: number): boolean {
        const state = this._currAni.getAnimationState(this.animation);
        if (this._currDt >= state.duration) {
            this._isCompelte = true;
            this._currDt -= state.duration;
            this._currAni.setCurrentTime(state.duration, this.animation);
            this._completeCallback && this._completeCallback(true);
            if (!CC_EDITOR) this.node.emit(PlayAnimation.Event.animationComplete);
            return false;
        } else {
            this._isCompelte = false;
            this._currAni.setCurrentTime(this._currDt, this.animation);
            this._currDt += dt;
            return true;
        }
    }

    /**
     * 播放动画
     * @param name 动作名字
     * @param playTimes 播放次数(默认无限循环)
     */
    play(name?: string, complete?: IComplete, playTimes = 0, playDelay = 0, loopInterval = 0) {
        this.playDelay = playDelay;
        this.loopInterval = loopInterval;
        // 先停止
        this.stop();

        if (typeof name === 'string') {
            this._animation = name;
        }
        playTimes = Math.floor(playTimes);
        this._completeCallback = complete || null;

        // 0代表不播放
        if (playTimes === 0) return false;
        // 播放失败
        if (!this._play(playTimes - 1)) return false;

        if (!CC_EDITOR) this.node.emit(PlayAnimation.Event.animationPlay);

        return true;
    }

    /**
     * 播放一次
     * @param name 动作名字
     */
    playOnce(name?: string, complete?: IComplete, playDelay = 0) {
        return this.play(name, complete, 1);
    }

    /**
     * 播放循环
     * @param name 动作名字
     */
    playLoop(name?: string, loopInterval = 0, complete?: IComplete, playDelay = 0) {
        return this.play(name, complete, -1, playDelay, loopInterval);
    }

    stop() {
        if (super.stop()) {
            this._currDt = 0;
            // 完成一次动画的中途被停止了
            if (this._isCompelte === false && this._completeCallback) {
                this._completeCallback(false);
                this._completeCallback = null;
            }
            if (!CC_EDITOR) this.node.emit(PlayAnimation.Event.animationStop);
            return true;
        }
        return false;
    }

    pause() {
        if (super.pause()) {
            if (!CC_EDITOR) this.node.emit(PlayAnimation.Event.animationPause);
            return true;
        }
        return false;
    }

    resume() {
        if (super.resume()) {
            if (!CC_EDITOR) this.node.emit(PlayAnimation.Event.animationResume);
            return true;
        }
        return false;
    }

    update(dt: number) {
        super.update(dt);

        if (CC_EDITOR) {
            if (this._currAni && this._currAni.playOnLoad) {
                //@ts-ignore
                Editor.info('不要使用cc.Animation的playOnLoad属性，请使用playAnimation的time属性代替');
                this._currAni.playOnLoad = false;
            }
        }
    }
}
